package com.controller;

import com.orm.ServiceCalledEntity;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by lirance on 16/5/4.
 */
public class Similarity {
    double sim1, sim;

    public double getSimilarity(int uid1, int uid2, int Gn) throws Exception {
        int num = 0;
        GetServiceCallList gsc = new GetServiceCallList();
        gsc.setGn(Gn);
        List<ServiceCalledEntity> sc1 = gsc.GetServiceCallListsByuId(uid1);
        List<ServiceCalledEntity> sc2 = gsc.GetServiceCallListsByuId(uid2);

       /* sc1 = gsc.GetServiceCallListsByuId(uid1);//用户1调用的服务列表
        sc2 = gsc.GetServiceCallListsByuId(uid2);//用户2调用的服务列表*/

        List<Integer> serList1 = new ArrayList<>();//用户1调用的服务列表
        for (int i = 0; i < sc1.size(); i++) {
            if (!serList1.contains(sc1.get(i).getWsId())) {
                serList1.add(sc1.get(i).getWsId());
            }
        }

        List<Integer> serList2 = new ArrayList<>();//用户2调用的服务列表
        for (int i = 0; i < sc2.size(); i++) {

            if (!serList2.contains(sc2.get(i).getWsId())) {
                serList2.add(sc2.get(i).getWsId());
            }
        }

        List<Integer> union = serList1;//并集
        List<Integer> shared = new ArrayList<>();//交集

        for (int i = 0; i < serList1.size(); i++) {/*
            union.add(serList1.get(i));//并集
            for (int j = 0; j < serList2.size(); j++) {
                if (serList1.get(i) == serList2.get(j)) {
                    shared.add(serList2.get(j)); //交集
                    break;
                } else union.add(serList2.get(j));//并集
            }*/
            if (serList2.contains(serList1.get(i))) {
                shared.add(serList1.get(i));  //交集
            }
        }


        for (int i = 0; i < serList2.size(); i++) {
            if (!union.contains(serList2.get(i))) {
                union.add(serList2.get(i));
            }
        }


        for (int i = 0; i < shared.size(); i++) {
            num = num + getFrequency(uid1, shared.get(i),Gn) + getFrequency(uid2, shared.get(i),Gn);
        }

        for (int i = 0; i < shared.size(); i++) {
            int num1 = getFrequency(uid1, shared.get(i),Gn);
            int num2 = getFrequency(uid2, shared.get(i),Gn);

            sim1 = sim1 + ((num1 + num2) * 1.000 / (num * (1 + Math.abs(getAverageVal(uid1, shared.get(i),Gn) - getAverageVal(uid2, shared.get(i),Gn)))));

        }

        sim = 2 * (shared.size()) * sim1 / union.size();

        return sim;
    }

    public double getAverageVal(int uid, int sid, int Gn) throws Exception {
        double val = 0, averageVal = 0;
        GetServiceCallList gsc = new GetServiceCallList();
        gsc.setGn(Gn);
        List<ServiceCalledEntity> list = gsc.GetServiceCallListsByusId(uid, sid);
        for (int i = 0; i < list.size(); i++) {
            val = val + list.get(i).getFrequency() * (list.get(i).getRtt());
        }
        averageVal = val * 1.00 / getFrequency(uid, sid,Gn);
        return averageVal;
    }

    private int getFrequency(int uid, int sid,int Gn) throws Exception {
        int frequency = 0;
        GetServiceCallList gsc = new GetServiceCallList();
        gsc.setGn(Gn);
        List<ServiceCalledEntity> list = gsc.GetServiceCallListsByusId(uid, sid);
        for (int i = 0; i < list.size(); i++) {
            frequency = frequency + list.get(i).getFrequency();
        }
        return frequency;

    }
}
